package org.wlgzs.office_exam_student.servlet;

import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.wlgzs.office_exam_student.entity.ChoiceQuestion;
import org.wlgzs.office_exam_student.entity.OperateQuestion;
import org.wlgzs.office_exam_student.entity.User;
import org.wlgzs.office_exam_student.permission.Authentication;
import org.wlgzs.office_exam_student.service.office.OfficeConfig;
import org.wlgzs.office_exam_student.service.office.ResolveResult;
import org.wlgzs.office_exam_student.service.office.ResolveTask;

@WebServlet("/mockExam")
public class MockExamServlet extends BaseServlet {

	private static final long serialVersionUID = 1L;
	private static final String resolveTasksKey = "resolveTasks";

	private final int choiceNum = 20;
	private final int wordNum = 1;
	private final int excelNum = 1;
	private final int pptNum = 1;

	private final static String MOCK_TITLE_1 = "计算机一级模拟考试";
	private final static String MOCK_TITLE_2 = "计算机二级模拟考试";

	private final static List<ChoiceQuestion> emptyChoice = new LinkedList<>();
	private final static List<OperateQuestion> emptyOperate = new LinkedList<>();

	private volatile List<OperateQuestion> words1 = new LinkedList<>();
	private volatile List<OperateQuestion> excels1 = new LinkedList<>();
	private volatile List<OperateQuestion> ppts1 = new LinkedList<>();

	private volatile List<OperateQuestion> words2 = new LinkedList<>();
	private volatile List<OperateQuestion> excels2 = new LinkedList<>();
	private volatile List<OperateQuestion> ppts2 = new LinkedList<>();

	@Override
	public void init(ServletConfig config) throws ServletException {
		super.init(config);
		Timer timer = new Timer(true);
		updateQuestions();
		timer.schedule(new TimerTask() {
			@Override
			public void run() {
				try {
					logger.debug("update mock operate questions.");
					updateQuestions();
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}, 300000, 300000);
	}

	private void updateQuestions() {
		synchronized (words1) {
			List<OperateQuestion> oqs = operateQuestionService.operateQuestions(0, wordNum, OperateQuestion.TYPE_WORD,
					OperateQuestion.GRADE_ONE);
			if (oqs != null) {
				words1 = oqs;
			}
			for(OperateQuestion oq:words1) {
				oq.setSourceUrl(OfficeConfig.renderFiles(oq.getSourceUrl()));
			}
		}
		synchronized (excels1) {
			List<OperateQuestion> oqs = operateQuestionService.operateQuestions(0, excelNum, OperateQuestion.TYPE_EXCEL,
					OperateQuestion.GRADE_ONE);
			if (oqs != null) {
				excels1 = oqs;
			}
			for(OperateQuestion oq:excels1) {
				oq.setSourceUrl(OfficeConfig.renderFiles(oq.getSourceUrl()));
			}
		}
		synchronized (ppts1) {
			List<OperateQuestion> oqs = operateQuestionService.operateQuestions(0, pptNum, OperateQuestion.TYPE_PPT,
					OperateQuestion.GRADE_ONE);
			if (oqs != null) {
				ppts1 = oqs;
			}
			for(OperateQuestion oq:ppts1) {
				oq.setSourceUrl(OfficeConfig.renderFiles(oq.getSourceUrl()));
			}
		}
		synchronized (words2) {
			List<OperateQuestion> oqs = operateQuestionService.operateQuestions(0, wordNum, OperateQuestion.TYPE_WORD,
					OperateQuestion.GRADE_TWO);
			if (oqs != null) {
				words2 = oqs;
			}
			for(OperateQuestion oq:words2) {
				oq.setSourceUrl(OfficeConfig.renderFiles(oq.getSourceUrl()));
			}
		}
		synchronized (excels2) {
			List<OperateQuestion> oqs = operateQuestionService.operateQuestions(0, excelNum, OperateQuestion.TYPE_EXCEL,
					OperateQuestion.GRADE_TWO);
			if (oqs != null) {
				excels2 = oqs;
			}
			for(OperateQuestion oq:excels2) {
				oq.setSourceUrl(OfficeConfig.renderFiles(oq.getSourceUrl()));
			}
		}
		synchronized (ppts2) {
			List<OperateQuestion> oqs = operateQuestionService.operateQuestions(0, pptNum, OperateQuestion.TYPE_PPT,
					OperateQuestion.GRADE_TWO);
			if (oqs != null) {
				ppts2 = oqs;
			}
			for(OperateQuestion oq:ppts2) {
				oq.setSourceUrl(OfficeConfig.renderFiles(oq.getSourceUrl()));
			}
		}
	}

	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		String operation = request.getParameter("operation");
		String paper = request.getParameter("paper");

		if ("score".equals(operation)) {
			logger.debug("operation: socre");
			this.respScore(request, response);
			return;
		}
		boolean flag = "1".equals(paper);
		String paperType = flag ? ChoiceQuestion.GRADE_ONE : ChoiceQuestion.GRADE_TWO;
		request.setAttribute("title",flag?MOCK_TITLE_1:MOCK_TITLE_2);
		//一级默认80分钟,二级默认120分钟
		//freemarker默认会改变数字显示格式,所以直接给字符串
		request.setAttribute("timeSec", flag?"4800":"7200");
		User user = Authentication.user();
		HttpSession ses = request.getSession();
		ses.setAttribute("action", "mock");
		int schoolId = user.getSchoolId();
		// 选择题只能选择学校内的题库，就不缓存了
		List<ChoiceQuestion> choices = emptyChoice;
		List<OperateQuestion> words = emptyOperate;
		List<OperateQuestion> excels = emptyOperate;
		List<OperateQuestion> ppts = emptyOperate;
		String type = request.getParameter("type");
		if(type!=null){
			request.setAttribute("type",type);
		}
		if (type == null) {
			choices = choiceQuestionService.choiceQuestions(schoolId, choiceNum, paperType);
            changeChoice(choices,"choiceImg?img=");
			words = flag?words1:words2;
			excels = flag?excels1:excels2;
			ppts =flag?ppts1:ppts2;
		}else {
			switch (type) {
			case "choice":
				choices = choiceQuestionService.choiceQuestions(schoolId, choiceNum, paperType);
                changeChoice(choices,"choiceImg?img=");
				break;
			case "word":
				words = flag?words1:words2;
				break;
			case "excel":
				excels = flag?excels1:excels2;
				break;
			case "ppt":
				ppts = flag?ppts1:ppts2;
				break;
			}
		}
		// 设置考试Id为0,代表模拟
		ses.setAttribute("examId", 0);
		// 解析任务
		List<ResolveTask> resolveTasks = new LinkedList<>();
		// 先存进去，下面对列表进行添加
		ses.setAttribute(resolveTasksKey, resolveTasks);
		// 模拟main界面传过来的参数

		request.setAttribute("choiceList", choices);
		request.setAttribute("word", words);
		request.setAttribute("excel", excels);
		request.setAttribute("ppt", ppts);

		int index = 0;
		for (OperateQuestion oq : words) {
			ResolveTask task = new ResolveTask(user.getId(), OfficeConfig.generateKey(oq.getId()),
					OfficeConfig.FileType.DOCX, OfficeConfig.PaperType.MOCK);
			task.setExamId(0);
			task.setIndex(index++);
			resolveTasks.add(task);
		}
		index = 0;
		for (OperateQuestion oq : excels) {
			ResolveTask task = new ResolveTask(user.getId(), OfficeConfig.generateKey(oq.getId()),
					OfficeConfig.FileType.XLSX, OfficeConfig.PaperType.MOCK);
			task.setExamId(0);
			task.setIndex(index++);
			resolveTasks.add(task);
		}
		index = 0;
		for (OperateQuestion oq : ppts) {
			ResolveTask task = new ResolveTask(user.getId(), OfficeConfig.generateKey(oq.getId()),
					OfficeConfig.FileType.PPTX, OfficeConfig.PaperType.MOCK);
			task.setExamId(0);
			task.setIndex(index++);
			resolveTasks.add(task);
		}
		render("mockExam");
	}
	public static void changeChoice(List<ChoiceQuestion> choices,String srcPath){
        /*
		for(ChoiceQuestion cq:choices){
            String title = cq.getTitle();
            String a = cq.getOptionA();
            String b = cq.getOptionB();
            String c = cq.getOptionC();
            String d = cq.getOptionD();
            if(title!=null && title.startsWith("#img#")){
				cq.setTitle(renderImg(srcPath,title));
            }
            if(a!=null && a.startsWith("#img#")){
				cq.setOptionA(renderImg(srcPath,a));
            }
            if(b!=null && b.startsWith("#img#")){
				cq.setOptionB(renderImg(srcPath,b));
            }if(c!=null && c.startsWith("#img#")){
				cq.setOptionC(renderImg(srcPath,c));
            }if(d!=null && d.startsWith("#img#")){
				cq.setOptionD(renderImg(srcPath,d));
            }
        }
        */
    }

    public static String renderImg(String srcPath,String name){
		name = name.substring(5);
		return String.format("<img class=\"choice-img\" src=\"%s%s\" />",srcPath,name);
	}

	/**
	 * @author song(mejeesong@qq.com)
	 * @date 2018年1月31日
	 * @param req
	 * @param res
	 *            当请求是分数时，运行此方法。
	 */
	private void respScore(HttpServletRequest req, HttpServletResponse res) {
		@SuppressWarnings("unchecked")
		List<ResolveTask> tasks = (List<ResolveTask>) req.getSession().getAttribute(resolveTasksKey);
		if (tasks == null) {
			tasks = new LinkedList<>();
		}
		StringBuilder respJson = new StringBuilder("{'code':'success','data':[ ");
		for (ResolveTask task : tasks) {
			// 此方法自动设置Task的id
			if (task.getId() < 1) {
				officeResolverService.addTask(task);
			}
			respJson.append('{');
			respJson.append("'type':'").append(task.getFileTypeStr());
			respJson.append("','index':").append(task.getIndex());
			long queue = officeResolverService.queryFront(task.getId());
			if(queue < 0)
			    queue = 0;
			if (task.getResolveResult() != null) {
				ResolveResult rr = task.getResolveResult();
				// 最后故意多加一个空格，没有错误之处时删除空格
				respJson.append(",'result':{'score':").append(rr.score).append(",'errors':[ ");
				if(rr.errors != null) {
					for (String error : rr.errors) {
						respJson.append("'").append(error).append("',");
					}
				}else {
					logger.warn(rr.toString()+",errors is null.");
				}
				respJson.deleteCharAt(respJson.length() - 1);
				respJson.append("]}");
				respJson.append(",'state':").append("'finish'}");
			} else {
				respJson.append(",'state':").append("'process',");
				respJson.append("'queue':").append(queue).append('}');
			}
			respJson.append(',');
		}
		respJson.deleteCharAt(respJson.length() - 1);
		respJson.append("]}");
		renderString(respJson.toString().replace("'", "\""));
	}

}
